/*
 * Copyright (c) 2010, 2011
 *	Open Source Technologies Ltd.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the company nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COMPANY AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#ifndef __BLISS64_STRING_H__
#define __BLISS64_STRING_H__

#define STRING_MAGIC 0x49820000
#define STRING_DEAD  0x4982DEAD

#ifndef __STRING_T__
#define __STRING_T__
typedef struct string_st string_t;
#endif /* !__STRING_T__ */

struct string_st
{
	uint32_t  s_magic;
	char     *s_buffer;
	size_t    s_capacity;
	size_t    s_length;
};

#define is_string(obj)      is_object(obj, s_magic, STRING_MAGIC)
#define is_string_dead(obj) is_object_dead(obj, s_magic, STRING_MAGIC)
#define is_string_opt(obj)  is_object_opt(obj, s_magic, STRING_MAGIC)

__begin_decls

string_t *string_create     __p((void));
void      string_initialize __p((string_t *str));

#ifndef NDEBUG

size_t    string_length   __p((const string_t *str));
size_t    string_capacity __p((const string_t *str));
char     *string_cstr     __p((const string_t *str));

#else /* NDEBUG */

#define string_length(str)   ((str)->s_length)
#define string_capacity(str) ((str)->s_capacity)
#define string_cstr(str)     ((str)->s_buffer ? (str)->s_buffer : "")

#endif /* NDEBUG */

string_t *string_append      __p((string_t *dest, const string_t *src));
string_t *string_append_mem  __p((string_t *dest, const char *src, size_t len));
string_t *string_append_cstr __p((string_t *dest, const char *src));
string_t *string_append_char __p((string_t *dest, char src));

int       string_compare      __p((const string_t *left, const string_t *right));
int       string_compare_mem  __p((const string_t *left, const char *right, size_t len));
int       string_compare_cstr __p((const string_t *left, const char *right));

void      string_finalize __p((string_t *str));
string_t *string_destroy  __p((string_t *str));

__end_decls

#endif /* !__BLISS64_STRING_H__ */
